<?php

declare(strict_types=1);
// +----------------------------------------------------------------------
// | swiftAdmin 极速开发框架 [基于WebMan开发]
// +----------------------------------------------------------------------
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
// +----------------------------------------------------------------------
// | swiftAdmin.net High Speed Development Framework
// +----------------------------------------------------------------------
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
// +----------------------------------------------------------------------
namespace app\admin\controller\system;


use app\AdminController;
use app\common\library\Ip2Region;
use app\common\model\system\Morder as Morders;
use app\common\model\system\Material;
use app\common\model\system\Formula;
use app\common\model\system\Product;
use app\common\model\system\OrderProduct;
use app\common\model\system\OrderMaterial;
use app\common\model\system\MaterialPrice;
use app\common\model\system\MaterialLog;
use app\common\model\system\ProductLog;
use app\common\model\system\PackageLog;
use support\Response;
use system\Random;
use think\facade\Db;

use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use Webman\Http\Request;
use think\Validate;


/**
 * 用户管理
 * Class User
 * @package app\admin\controller\system
 */
class Morder extends AdminController
{
    // 初始化函数
    public function __construct()
    {
        parent::__construct();
        $this->model = new Morders();
    }

    /**
     * 获取资源
     * @return Response
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function index(): \support\Response
    {

        if (request()->isAjax()) {
            // 获取数据
            $post = \request()->all();
            $page = (int)input('page') ?? 1;
            $limit = (int)input('limit') ?? 10;
            // 生成查询条件
            $where = array();
            if (!empty($post['title'])) {
                $time = explode('~', $post['title']);
                $start = trim($time[0] ?? date('Y-m-d'));
                $end = trim($time[1] ?? date('Y-m-d', time() + 86400));
                $where[] = ['create_time', 'between', [strtotime($start), strtotime($end)]];
            }
            $count = $this->model->where($where)->count();
            $page = ($count <= $limit) ? 1 : $page;
            $list = $this->model->where($where)->order("id desc")->limit((int)$limit)->page((int)$page)->select();
            return $this->success('查询成功', "", $list, $count);
        }
        return view('/system/morder/index', []);
    }

    /**
     * 添加订单
     */
    public function add()
    {
        if (request()->isPost()) {
            $post = request()->post();
            $post = request_validate_rules($post, get_class($this->model));
            if (empty($post) || !is_array($post)) {
                return $this->error($post);
            }
            if ($this->model->create($post)) {
                return $this->success('添加成功！');
            }
            return $this->error('添加失败！');
        }
    }

    /**
     * 添加配方
     */
    public function edit()
    {
        $id = input('id');
        if (request()->isPost()) {
            $post = \request()->post();
            // 查询数据
            $validate = (new Validate())->rule([
                'id' => 'require',
                'guo' => 'require',
                'goodid' => 'require',
                'spec' => 'require',
                'peifang' => 'require'
            ]);
            $validate->message([
                'id.require' => '关联订单ID不能为空',
                'guo.require' => '锅数不能为空',
                'spec.require' => '规格不能为空',
                'goodid.require' => '产品不能为空',
                'peifang.require' => '配方不能为空'
            ]);
            if (!$validate->check($post)) {
                return $this->error($validate->getError());
            }
            $good = (new Product())->where('id', $post['goodid'])->find();
            if (empty($good)) {
                return $this->error('产品不存在，请刷新重试');
            }
            $post['title'] = $good['title'];
            $order = $this->model->where('id', $post['id'])->find();
            if (empty($order)) {
                return $this->error('订单不存在或已删除');
            }
            $post['title'] = trim($post['title']);
            //获取配方材料明细
            $formula = (new Formula())->where('id', $post['peifang'])->value('list') ?? '';
            $post['list'] = json_decode($formula, true) ?? [];
            //计算一锅总重
            $guoweight = 0;
            foreach ($post['list'] as $ordermetrial) {
                $guoweight +=  (float)$ordermetrial['size'];
            }
            Db::startTrans();
            try {
                //插入产品订单
                $orderproduct = [
                    'orderid' => $post['id'],
                    'ordersn' => $order['ordersn'],
                    'productid' => $post['goodid'],
                    'formulaid' => $post['peifang'],
                    'product_name' =>  $post['title'],
                    'product_codes' =>  $good['codes'],
                    'weights' =>  $guoweight * $post['guo'],
                    'guo' => $post['guo'],
                    'product_spec' => $post['spec'],
                    'remark' =>  $post['remark'] ?? '',
                    'total' => 0
                ];
                $res2 = (new OrderProduct())->create($orderproduct);
                //关联原材料
                $material = [];
                foreach ($post['list'] as $ordermetrial) {
                    $size = (float)$ordermetrial['size'] ?? 0;
                    $weights = (float)($size * $post['guo']);
                    //获取原材料价格
                    $price = 0;
                    if ($weights > 0) {
                        $price = (new MaterialPrice())->where('dates', '<=', $order['ordersn'])->where('materialid', $ordermetrial['material'])->value('price') ?? 0;
                        if (empty($price)) {
                            return $this->error('请先上传当前下单日期前原材料[' . $ordermetrial['matitle'] . ']进货记录');
                        }
                    }
                    $orderproduct['total'] += $price * $weights;
                    (new OrderMaterial())->create([
                        'ordersn' => $order['ordersn'],
                        'orderid' => $post['id'],
                        'orderproductid' => $res2->id,
                        'productid' => $post['goodid'],
                        'materialid' => $ordermetrial['material'],
                        'materialtitle' => $ordermetrial['matitle'],
                        'formulaid' => $post['peifang'],
                        'size' => (float)$size,
                        'weights' => $weights,
                        'guo' => $post['guo'],
                        'price' => $price
                    ]);
                    (new MaterialLog())->MaterialSkuEdit(
                        $ordermetrial['material'],
                        -$weights,
                        2,
                        $order['ordersn'],
                        '订单ID:' . $order['id'] . '新增产品'
                    );
                }
                (new OrderProduct())->where('id', $res2->id)->update(['total' => $orderproduct['total']]);
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                return $this->error($e->getMessage());
            }
            return $this->success('操作成功！');
        }
        $data = $this->model->find($id);
        //顶级栏目
        $formula = (new Formula())->where('topid', 0)->field('id,title')->select();
        foreach ($formula as $mulas) {
            $mulas['children'] = (new Formula())->where('topid', $mulas['id'])->field('id,title')->select();
        }
        $material = (new Material())->field('id,title')->select();
        $productlist = (new Product())->select();
        //订单明细
        $orderproduct = (new OrderProduct())->where('orderid', $id)->select();
        $heji = [
            'dun' => 0,
            'guo' => 0,
            'yuji' => 0,
            'sjnumber' =>0,
            'sjsl' => 0
        ];
        $peifangsm = [];
        foreach ($orderproduct as $product) {
            $heji['dun'] += $product['weights'];
            $heji['guo'] += $product['guo'];
            $product['material'] = '';
            $materials = (new OrderMaterial())->where('orderproductid', $product['id'])->select();
            foreach ($materials as $materiala) {
                $product['material'] .= '【' . $materiala['materialtitle'] . '】';
                $product['materialxj'] .= '【' . $materiala['materialtitle']  . (float)$materiala['size'] . '】';
            }
            if (empty($peifangsm[$product['formulaid']])) {
                $peifangsm[$product['formulaid']] = [
                    'id' => $product['formulaid'],
                    'text' => $product['materialxj'],
                    'xuhao' => count($peifangsm) + 1
                ];
            }
            $product['xuhao'] = $peifangsm[$product['formulaid']]['xuhao'] ?? 0;
            //计算预计生产数量
            $product['yuji'] = 0;
            $number = 0;
            $str = trim(strtolower($product['product_spec'])) ?? ""; //大写转小写去掉俩端空格
            if (strpos($str, "k")) {
                $number = (float)(substr_replace($str, "", strpos($str, "k")) ?? 0); //去掉指定字符串后内容并转浮点计算
            }
            if ($number > 0) {
                $product['yuji'] = floor($product['weights'] / $number);
            }
            $product['number'] = $number;
            $heji['yuji'] += $product['yuji'];
            $heji['sjnumber'] += $number * $product['product_number'];
            $heji['sjsl'] +=$product['product_number'];

        }
        //所有配方
        $allmaterial = (new OrderMaterial())->field('materialtitle,sum(weights) as weightsall,materialid')
            ->order('weightsall desc')->group('materialid')->where('orderid', $id)
            ->select();
        return view('/system/morder/edit', [
            'data' => $data,
            'formula' => $formula,
            'material' => $material,
            'orderproduct' => $orderproduct,
            'allmaterial' => $allmaterial,
            'productlist' => $productlist,
            'heji' => $heji,
            'peifangsm' => $peifangsm
        ]);
    }


    /**
     * 编辑实际生产数量
     */
    public function pnumber()
    {
        $id = input('id');
        if (request()->isPost()) {
            $post = \request()->post();
            // 查询数据
            $validate = (new Validate())->rule([
                'id' => 'require',
                'product_number' => 'require|egt:0'
            ]);
            $validate->message([
                'id.require' => '关联订单产品ID不能为空',
                'product_number.require' => '实际数量不能为空',
                'egt.require' => '实际数量必须大于等于0',
            ]);
            if (!$validate->check($post)) {
                return $this->error($validate->getError());
            }
            $oproduct = (new OrderProduct())->where('id', $post['id'])->find();
            if (empty($oproduct)) {
                return $this->error('生产产品不存在或已删除，请刷新页面重试');
            }
            $good = (new Product())->where('id', $oproduct['productid'])->find();
            if (empty($good)) {
                return $this->error('产品不存在或已删除');
            }
            $order = $this->model->where('id', $oproduct['orderid'])->find();
            if (empty($order)) {
                return $this->error('订单不存在或已删除，请刷新页面重试');
            }
            //变更数量
            $sjnumber = $post['product_number'] - $oproduct['product_number'];
            if (empty($sjnumber) || $sjnumber == 0) {
                return $this->error('实际数量未变更');
            }
            Db::startTrans();
            try {
                (new OrderProduct())->update(['id' => $post['id'], 'product_number' => $post['product_number']]);
                //变更库存
                (new ProductLog())->ProductSkuEdit($oproduct['productid'], $sjnumber, 3, '生产订单录入', 0, $post['id']);
                //变更包装
                (new PackageLog())->ProductPackEdit($oproduct['productid'], -$sjnumber, 3, '生产订单产品录入变更', 0, $post['id']);
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                return $this->error($e->getMessage());
            }
            return $this->success('操作成功！');
        }
        $data = (new OrderProduct())->find($id);
        return view('/system/morder/pnumber', [
            'data' => $data
        ]);
    }

    /**
     * 编辑配方
     */
    public function pedit()
    {
        $id = input('id');
        if (request()->isPost()) {
            $post = \request()->post();
            // 查询数据
            $validate = (new Validate())->rule([
                'id' => 'require',
                'goodid' => 'require',
                'guo' => 'require',
                'spec' => 'require'
            ]);
            $validate->message([
                'id.require' => '关联订单产品ID不能为空',
                'goodid.require' => '产品不能为空',
                'guo.require' => '重量不能为空',
                'spec.require' => '规格不能为空'
            ]);
            if (!$validate->check($post)) {
                return $this->error($validate->getError());
            }
            $good = (new Product())->where('id', $post['goodid'])->find();
            if (empty($good)) {
                return $this->error('产品不存在或已删除，请刷新重试');
            }
            $post['title'] = $good['title'];
            $oproduct = (new OrderProduct())->where('id', $post['id'])->find();
            if (empty($oproduct)) {
                return $this->error('生产产品不存在或已删除，请刷新页面重试');
            }
            $order = $this->model->where('id', $oproduct['orderid'])->find();
            if (empty($order)) {
                return $this->error('订单不存在或已删除，请刷新页面重试');
            }
            $post['title'] = trim($post['title']);
            $materialarrs = [];
            //一个配方一锅的重量
            $oneweights = 0;
            $total = 0;
            if ($post['guo'] != $oproduct['guo']) {
                $materials = (new OrderMaterial())->where('orderproductid', $post['id'])->select();
                foreach ($materials as $material) {
                    $oneweights += $material['size'];
                    //获取原材料价格
                    $price = 0;
                    if (($material['size'] * $post['guo']) > 0) {
                        $price = (new MaterialPrice())->where('dates', '<=', $order['ordersn'])->where('materialid', $material['materialid'])->value('price') ?? 0;
                        if (empty($price)) {
                            //return $this->error('请先上传当前下单日期前原材料[' . $material['materialtitle'] . ']进货记录');
                        }
                    }
                    $materialarrs[] = [
                        'id' => $material['id'],
                        'guo' => $post['guo'],
                        'productid' => $post['goodid'],
                        'materialid' => $material['materialid'],
                        'weights_befores' => $material['weights'], //变化前原材料重量
                        'weights' => $material['size'] * $post['guo'], //变化后原材料重量
                        'price' => $price
                    ];
                    $total += $price * $material['size'] * $post['guo'];
                }
            } elseif ($post['goodid'] != $oproduct['productid']) {
                return $this->error('产品不可更改');
                $materials = (new OrderMaterial())->where('orderproductid', $post['id'])->select();
                foreach ($materials as $material) {
                    //获取原材料价格
                    $price = 0;
                    if ($material['weights'] > 0) {
                        $price = (new MaterialPrice())->where('dates', '<=', $order['ordersn'])->where('materialid', $material['materialid'])->value('price') ?? 0;
                        if (empty($price)) {
                            //return $this->error('请先上传当前下单日期前原材料[' . $material['materialtitle'] . ']进货记录');
                        }
                    }
                    $materialarrs[] = [
                        'id' => $material['id'],
                        'productid' => $post['goodid'],
                        'materialid' => $material['materialid'],
                        'weights_befores' => $material['weights'], //变化前原材料重量
                        'weights' => $material['weights'], //变化后原材料重量
                    ];
                    $total += $price * $material['size'] * $post['guo'];
                }
            } else {
                $oneweights = (new OrderMaterial())->where('orderproductid', $post['id'])->sum('size');
            }
            Db::startTrans();
            try {
                //更新产品订单
                $orderproduct = [
                    'id' => $oproduct['id'],
                    'orderid' => $oproduct['orderid'],
                    'productid' => $post['goodid'],
                    'formulaid' => $post['peifang'],
                    'product_name' =>  $post['title'],
                    'product_spec' => $post['spec'],
                    'product_codes' =>  $good['codes'],
                    'guo' => $post['guo'],
                    'weights' => $oneweights * $post['guo'],
                    'remark' =>  $post['remark'] ?? '',
                    'total' => $total
                ];
                (new OrderProduct())->update($orderproduct);
                if (count($materialarrs) > 0) {
                    foreach ($materialarrs as $materialarr) {
                        $weights = 0;
                        if ($materialarr['weights_befores'] < $materialarr['weights']) {
                            $weights = $materialarr['weights_befores'] - $materialarr['weights'];
                        } else {
                            $weights = $materialarr['weights'] - $materialarr['weights_befores'];
                        }
                        (new OrderMaterial())->update($materialarr);
                        (new MaterialLog())->MaterialSkuEdit(
                            $materialarr['materialid'],
                            $weights,
                            2,
                            $order['ordersn'],
                            '订单ID:' . $order['id'] . '修改产品数据'
                        );
                    }
                }
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                return $this->error($e->getMessage());
            }
            return $this->success('操作成功！');
        }
        $data = (new OrderProduct)->find($id);
        if ($data) {
            $data['list'] = (new OrderMaterial())->where('orderproductid', $id)->select();
        }
        //顶级栏目
        $formula = (new Formula())->where('topid', 0)->field('id,title')->select();
        foreach ($formula as $mulas) {
            $mulas['children'] = (new Formula())->where('topid', $mulas['id'])->field('id,title')->select();
        }
        $material = (new Material())->field('id,title')->select();
        $productlist = (new Product())->select();
        return view('/system/morder/pedit', [
            'data' => $data,
            'formula' => $formula,
            'productlist' => $productlist,
            'material' => $material
        ]);
    }

    public function pdel()
    {
        $id = input('id');
        if (!empty($id) && is_numeric($id)) {
            if (is_array($id)) {
                return $this->error('数据类型出现错误');
            }
            $orderproduct = (new OrderProduct())->where(['id' => $id])->find();
            if (empty($orderproduct)) {
                return $this->error('订单产品不存在或已删除，请刷新页面重试');
            }
            $order = $this->model->where('id', $orderproduct['orderid'])->find();
            if (empty($order)) {
                return $this->error('订单不存在或已删除，请刷新页面重试');
            }
            $materialarrs = (new OrderMaterial())->where('orderproductid', $id)->select();
            Db::startTrans();
            try {
                (new OrderProduct())::destroy($id);
                (new OrderMaterial())::destroy(['orderproductid' => $id]);
                foreach ($materialarrs as $materialarr) {
                    (new MaterialLog())->MaterialSkuEdit(
                        $materialarr['materialid'],
                        $materialarr['weights'],
                        2,
                        $order['ordersn'],
                        '订单ID:' . $order['id'] . '产品删除原材料库存返还'
                    );
                }
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                return $this->error($e->getMessage());
            }
            return $this->success('操作成功！');
        }
        return $this->error('删除失败，请检查您的参数！');
    }
}
